﻿using Autofac;
using Pay.Core;
using Pay.DTO;
using Pay.IService;
using Pay.TO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace Pay.Token.Utils {
    /// <summary>
    /// 分销统一接口
    /// </summary>
    public interface IUpDistribution {
        /// <summary>
        /// 分润计算
        /// </summary>
        /// <param name="merchant_id"></param>
        /// <param name="user_type"></param>
        /// <param name="order_item"></param>
        /// <returns></returns>
        List<bind_merchant_item> Handler(long merchant_id, UserType user_type,order_item_dto order_item);
    }
    /// <summary>
    /// 分销基础类
    /// </summary>
    public class DistributionBase {
        /// <summary>
        /// 用户信息
        /// </summary>
        private IMerchantService _iMerchantService;
        /// <summary>
        /// 创客商品信息
        /// </summary>
        private IProductTokenMakerService _iProductTokenMakerService;
        /// <summary>
        /// 活动商品信息
        /// </summary>
        private IProductActivityService _iProductActivityService;
        /// <summary>
        /// 分润集合
        /// </summary>
        protected List<bind_merchant_item> binds;
        /// <summary>
        /// 已分配用户
        /// </summary>
        protected Dictionary<UserType, merchant_dto> dicUses;
        /// <summary>
        /// 系统分配商户号
        /// </summary>
        protected const string system_no = "20000";
        /// <summary>
        /// 商品分销比例配置信息
        /// </summary>
        protected product_token_maker_dto_ex productToken;
        /// <summary>
        /// 商品信息
        /// </summary>
        protected product_dto product;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="iMerchantService"></param>
        /// <param name="iProductActivityService"></param>
        public DistributionBase(IMerchantService iMerchantService, IProductTokenMakerService iProductTokenMakerService, IProductActivityService iProductActivityService) {
            _iMerchantService = iMerchantService;
            _iProductTokenMakerService = iProductTokenMakerService;
            _iProductActivityService = iProductActivityService;
            binds = new List<bind_merchant_item>();
            dicUses = new Dictionary<UserType, merchant_dto>();
        }
        /// <summary>
        /// 获取上级用户
        /// </summary>
        /// <param name="merchant_id"></param>
        /// <returns></returns>
        protected IEnumerable<merchant_dto> GetParents(long merchant_id) {
            return _iMerchantService.GetParents(merchant_id);
        }
        /// <summary>
        /// 获取商品分销价格
        /// </summary>
        /// <param name="order_item"></param>
        /// <returns></returns>
        protected decimal GetAmount(order_item_dto order_item) {
            productToken = _iProductTokenMakerService.GetByProductId(order_item.product_id);
            product = productToken.product_activity.product;
            //产品活动处理
            product = _iProductActivityService.ProductActivityHandle(product);
            return (productToken.product_activity.product == null ? 0 : productToken.distribution_price);
        }
        /// <summary>
        /// 计算系统获得分润
        /// </summary>
        /// <param name="sysAmount"></param>
        protected void CalcSysProfit(decimal sysAmount) {
            if (sysAmount > 0) {
                decimal percent = 1 - binds.Sum(c => c.percent);
                binds.Add(new bind_merchant_item {
                    merchant_no = system_no,
                    amount = sysAmount,
                    freeze = true,
                    percent = percent
                });
            }
        }
    }
    /// <summary>
    /// 升级创客分润算法
    /// </summary>
    public class TokenMakerUpDistribution : DistributionBase, IUpDistribution {
        private Dictionary<UserType, decimal> dicUserProfits;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="iMerchantService"></param>
        /// <param name="iProductActivityService"></param>
        public TokenMakerUpDistribution(IMerchantService iMerchantService, IProductTokenMakerService iProductTokenMakerService,IProductActivityService iProductActivityService)
            : base(iMerchantService, iProductTokenMakerService, iProductActivityService) {
            dicUserProfits = new Dictionary<UserType, decimal>();
        }
        /// <summary>
        /// 分润计算方法
        /// </summary>
        /// <param name="merchant_id"></param>
        /// <param name="user_type"></param>
        /// <param name="order_item"></param>
        /// <returns></returns>
        public List<bind_merchant_item> Handler(long merchant_id, UserType user_type,order_item_dto order_item) {
            var log = IocHelper.Get<ILogHelper>("info");
            var parents = GetParents(merchant_id);
            if (parents != null)
                log.Info(parents.Select(c => "mobile：" + c.mobile + "，MerchantNo：" + c.merchant_no + "，UserType：" + c.usertype.ToDescription()).ToList().ToJson());
            var amount = GetAmount(order_item);
            dicUserProfits.Add(UserType.tokenNodeMall, productToken.node_mall_rate);
            dicUserProfits.Add(UserType.tokenCountyAgent, productToken.county_agent_rate);
            dicUserProfits.Add(UserType.tokenCityAgent, productToken.city_agent_rate);
            var userType = UserType.user;
            decimal money = 0;
            var firstUser = parents.FirstOrDefault(c => c.usertype.Value > UserType.user);
            if (firstUser != null) {
                //一级分销
                binds.Add(new bind_merchant_item {
                    merchant_no = firstUser.merchant_no,
                    amount = (amount * productToken.first_rate).RoundDown(2),
                    freeze = true,
                    is_bus = false,
                    product_id = order_item.product_id,
                    sku_id = order_item.sku_id ?? 0,
                    product_name = product.name
                });
                log.Info(string.Format("用户：{0}，获取分润：{1}", firstUser.name, (amount * productToken.first_rate).RoundDown(2)));
                if (firstUser.usertype.Value == UserType.tokenNodeMall) {
                    money = (amount * dicUserProfits[firstUser.usertype.Value]).RoundDown(2);
                    binds.Add(new bind_merchant_item {
                        merchant_no = firstUser.merchant_no,
                        amount = money,
                        freeze = true,
                        is_bus = true,
                        product_id =order_item.product_id,
                        sku_id = order_item.sku_id ?? 0,
                        product_name = product.name
                    });
                    log.Info(string.Format("用户：{0}，获取分润：{1}", firstUser.name, money));
                } else if (firstUser.usertype.Value == UserType.tokenCountyAgent) {
                    money = (amount * (dicUserProfits[firstUser.usertype.Value] + dicUserProfits[UserType.tokenNodeMall])).RoundDown(2);
                    binds.Add(new bind_merchant_item {
                        merchant_no = firstUser.merchant_no,
                        amount = money,
                        freeze = true,
                        is_bus = true,
                        product_id = order_item.product_id,
                        sku_id = order_item.sku_id ?? 0,
                        product_name = product.name
                    });
                    log.Info(string.Format("用户：{0}，获取分润：{1}", firstUser.name, money));
                } else if (firstUser.usertype.Value == UserType.tokenCityAgent) {
                    money = (amount * dicUserProfits.Sum(c => c.Value)).RoundDown(2);
                    binds.Add(new bind_merchant_item {
                        merchant_no = firstUser.merchant_no,
                        amount = money,
                        freeze = true,
                        is_bus = true,
                        product_id = order_item.product_id,
                        sku_id = order_item.sku_id ?? 0,
                        product_name = product.name
                    });
                    log.Info(string.Format("用户：{0}，获取分润：{1}", firstUser.name, money));
                }
                userType = firstUser.usertype.Value;
                var twoUser = parents.FirstOrDefault(c => c.usertype.Value > UserType.user && c.id != firstUser.id);
                if (twoUser != null) {
                    //二级分销
                    binds.Add(new bind_merchant_item {
                        merchant_no = twoUser.merchant_no,
                        amount = (amount * productToken.second_rate).RoundDown(2),
                        freeze = true,
                        is_bus = false,
                        product_id = order_item.product_id,
                        sku_id = order_item.sku_id ?? 0,
                        product_name = product.name
                    });
                    log.Info(string.Format("用户：{0}，获取分润：{1}", twoUser.name, (amount * productToken.second_rate).RoundDown(2)));
                    if (twoUser.usertype.Value > firstUser.usertype.Value) {
                        if (twoUser.usertype.Value == UserType.tokenNodeMall) {
                            money = (amount * dicUserProfits[twoUser.usertype.Value]).RoundDown(2);
                            binds.Add(new bind_merchant_item {
                                merchant_no = twoUser.merchant_no,
                                amount = money,
                                freeze = true,
                                is_bus = true,
                                product_id = order_item.product_id,
                                sku_id = order_item.sku_id ?? 0,
                                product_name = product.name
                            });
                            log.Info(string.Format("用户：{0}，获取分润：{1}", twoUser.name, money));
                        } else if (twoUser.usertype.Value == UserType.tokenCountyAgent) {
                            decimal dis_amount = 0;
                            dis_amount = (money > 0 ? (amount * dicUserProfits[UserType.tokenNodeMall]).RoundDown(2) : (amount * (dicUserProfits[twoUser.usertype.Value] + dicUserProfits[UserType.tokenNodeMall])).RoundDown(2));
                            money = amount * (dicUserProfits[twoUser.usertype.Value] + dicUserProfits[UserType.tokenNodeMall]);
                            binds.Add(new bind_merchant_item {
                                merchant_no = twoUser.merchant_no,
                                amount = dis_amount,
                                freeze = true,
                                is_bus = true,
                                product_id = order_item.product_id,
                                sku_id = order_item.sku_id ?? 0,
                                product_name = product.name
                            });
                            log.Info(string.Format("用户：{0}，获取分润：{1}", twoUser.name, dis_amount));
                        } else if (twoUser.usertype.Value == UserType.tokenCityAgent) {
                            binds.Add(new bind_merchant_item {
                                merchant_no = twoUser.merchant_no,
                                amount = (amount * dicUserProfits.Sum(c => c.Value) - money).RoundDown(2),
                                freeze = true,
                                is_bus = true,
                                product_id = order_item.product_id,
                                sku_id = order_item.sku_id ?? 0,
                                product_name = product.name
                            });
                            log.Info(string.Format("用户：{0}，获取分润：{1}", twoUser.name, (amount * dicUserProfits.Sum(c => c.Value) - money).RoundDown(2)));
                        }
                        userType = twoUser.usertype.Value;
                    }
                }
            }
            if (userType != UserType.tokenCityAgent) {
                foreach (var parent in parents) {
                    if (parent.usertype.Value <= userType)
                        continue;
                    if (parent.usertype.Value == UserType.tokenNodeMall) {
                        money = (amount * dicUserProfits[parent.usertype.Value]).RoundDown(2);
                        binds.Add(new bind_merchant_item {
                            merchant_no = parent.merchant_no,
                            amount = money,
                            freeze = true,
                            is_bus = true,
                            product_id = order_item.product_id,
                            sku_id = order_item.sku_id ?? 0,
                            product_name = product.name
                        });
                        log.Info(string.Format("用户：{0}，获取分润：{1}", parent.name, money));
                    } else if (parent.usertype.Value == UserType.tokenCountyAgent) {
                        decimal dis_amount = 0;
                        dis_amount = (money > 0 ? (amount * dicUserProfits[parent.usertype.Value]).RoundDown(2) : (amount * (dicUserProfits[parent.usertype.Value] + dicUserProfits[UserType.tokenNodeMall])).RoundDown(2));
                        money = amount * (dicUserProfits[parent.usertype.Value] + dicUserProfits[UserType.tokenNodeMall]);
                        binds.Add(new bind_merchant_item {
                            merchant_no = parent.merchant_no,
                            amount = dis_amount,
                            freeze = true,
                            is_bus = true,
                            product_id = order_item.product_id,
                            sku_id = order_item.sku_id ?? 0,
                            product_name = product.name
                        });
                        log.Info(string.Format("用户：{0}，获取分润：{1}", parent.name, dis_amount));
                    } else if (parent.usertype.Value == UserType.tokenCityAgent) {
                        binds.Add(new bind_merchant_item {
                            merchant_no = parent.merchant_no,
                            amount = (amount * dicUserProfits.Sum(c => c.Value) - money).RoundDown(2),
                            freeze = true,
                            is_bus = true,
                            product_id = order_item.product_id,
                            sku_id = order_item.sku_id ?? 0,
                            product_name = product.name
                        });
                        log.Info(string.Format("用户：{0}，获取分润：{1}", parent.name, (amount * dicUserProfits.Sum(c => c.Value) - money).RoundDown(2)));
                        break;
                    }
                    userType = parent.usertype.Value;
                }
            }
            decimal total = binds.Sum(c => c.amount);
            decimal sysAmount = amount - binds.Sum(c => c.amount);
            //CalcSysProfit(sysAmount);
            return binds;
        }
    }
    /// <summary>
    /// 升级业务
    /// </summary>
    public class UpGradeFade {
        /// <summary>
        /// 计算398购买商品分润算法
        /// </summary>
        /// <param name="componentContext"></param>
        /// <param name="invite_id"></param>
        /// <param name="user_type"></param>
        /// <param name="order_item"></param>
        /// <returns></returns>
        public static List<bind_merchant_item> CalcMallProfits(IComponentContext componentContext, long invite_id, UserType user_type,order_item_dto order_item) {
            var _distribution = componentContext.ResolveKeyed<IUpDistribution>(user_type);
            var binds = _distribution.Handler(invite_id, user_type, order_item);
            var log = IocHelper.Get<ILogHelper>("info");
            log.Info(binds.ToJson());
            return binds;
        }
    }
}